package org.web.standardplatform.client.builder;

import com.alibaba.druid.DbType;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.web.base.helper.FileHelper;
import org.web.base.helper.excel.ExcelOperatorHelper;
import org.web.standardplatform.client.domain.attribute.AttributeDTO;
import org.web.standardplatform.client.domain.attribute.ColumnAttributeDTO;
import org.web.standardplatform.client.domain.attribute.JavaAttributeDTO;
import org.web.standardplatform.client.domain.attribute.JavaAttributeExtendDTO;
import org.web.standardplatform.client.domain.attribute.type.BooleanFLAG;
import org.web.standardplatform.client.domain.attribute.type.SelectorType;
import org.web.standardplatform.client.domain.attribute.view.TransferViewSettingDTO;
import org.web.standardplatform.client.domain.buildproject.ProjectDefinitionDO;
import org.web.standardplatform.client.domain.check.ColumnInfoDTO;
import org.web.standardplatform.client.domain.check.TableInfoDTO;
import org.web.standardplatform.client.helper.TableSqlCheckHelper;


import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SqlConverterHelper {

    public static void main(String[] args) throws Exception {
        String createTableSql = FileHelper.convertStreamToString(new FileInputStream(new File("D:\\sql.txt")));
        List<String> sqlList = new ArrayList<>();
        sqlList.add(createTableSql);
        List<TableInfoDTO> tableInfoDTOList = TableSqlCheckHelper.parseByTableType(sqlList, DbType.mysql);
        ProjectDefinitionDO projectDefinitionDO = new ProjectDefinitionDO();
        projectDefinitionDO.setGroupId("org.web");
        projectDefinitionDO.setArtifactId("web-display");
        projectDefinitionDO.init();
        projectDefinitionDO.getParentProjectDefinitionDO().setJavaVersion("21");
        paresBatchSqlList(projectDefinitionDO, tableInfoDTOList, "D:\\test33.xlsx");
        //buildExcel(projectDefinitionDO, tableInfoDTOList.get(0), "D:\\test4.xlsx");
    }

    public static void paresBatchSqlList(ProjectDefinitionDO projectDefinitionDO, List<TableInfoDTO> tableInfoDTOList, String targetFileName) throws IOException {

        String absolutePath = Objects.requireNonNull(SqlConverterHelper.class.getResource("/")).getPath();
        File modelFile = new File(absolutePath + File.separator + "model.xlsx");

        FileInputStream modelInputStream = new FileInputStream(modelFile);
        File file = new File(targetFileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        // 复制文件内容
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = modelInputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        outputStream = new FileOutputStream(file);
        modelInputStream = new FileInputStream(modelFile);
        Workbook workbook = new XSSFWorkbook(modelInputStream);
        Sheet sourceSheet = workbook.getSheet("example");

        Sheet mainSheet = workbook.getSheet("main");
        int rowNum = mainSheet.getLastRowNum();
        for (TableInfoDTO tableInfoDTO : tableInfoDTOList) {
            Sheet targetSheet = workbook.createSheet(tableInfoDTO.getTableName());
            ExcelOperatorHelper.copySheet(sourceSheet, targetSheet);
            List<AttributeDTO> attributeDTOList = buildAttributeDTOList(tableInfoDTO);
            int rowIndex = 0;
            for (AttributeDTO attributeDTO : attributeDTOList) {
                Row row = targetSheet.createRow(4 + rowIndex++);
                row.createCell(0).setCellValue(rowIndex);
                row.createCell(1).setCellValue(attributeDTO.getColumnName());
                row.createCell(2).setCellValue(attributeDTO.getColumnAttribute().getColumnType());
                row.createCell(3).setCellValue(attributeDTO.getColumnAttribute().getAllowNull().toString());
                row.createCell(4).setCellValue(attributeDTO.getColumnAttribute().getColumnLength());
                row.createCell(5).setCellValue(attributeDTO.getColumnAttribute().getShortName());
                row.createCell(6).setCellValue(attributeDTO.getColumnAttribute().getShortComment());
                row.createCell(7).setCellValue(attributeDTO.getColumnAttribute().getDetailComment());

                row.createCell(8).setCellValue(attributeDTO.getJavaAttribute().getAttributeName());
                row.createCell(9).setCellValue(attributeDTO.getJavaAttribute().getAttributeType());

//            if (attributeDTO.getJavaAttribute().getJavaAttributeExtendJson() != null) {
//                row.createCell(10).setCellValue(attributeDTO.getJavaAttribute().getJavaAttributeExtendJson());
//            }

                if (attributeDTO.getJavaAttribute().getSupportEqual() != null) {
                    row.createCell(10).setCellValue(attributeDTO.getJavaAttribute().getSupportEqual());
                }
                if (attributeDTO.getJavaAttribute().getSupportIn() != null) {
                    row.createCell(11).setCellValue(attributeDTO.getJavaAttribute().getSupportIn());
                }
                if (attributeDTO.getJavaAttribute().getSupportCompare() != null) {
                    row.createCell(12).setCellValue(attributeDTO.getJavaAttribute().getSupportCompare());
                }
                if (attributeDTO.getJavaAttribute().getSupportFuzzy() != null) {
                    row.createCell(13).setCellValue(attributeDTO.getJavaAttribute().getSupportFuzzy());
                }
                if (attributeDTO.getJavaAttribute().getDtoRules() != null) {
                    row.createCell(14).setCellValue(attributeDTO.getJavaAttribute().getDtoRules());
                }
                if (attributeDTO.getJavaAttribute().getDtoRules() != null) {
                    row.createCell(15).setCellValue(attributeDTO.getJavaAttribute().getDomainRules());
                }

                if (attributeDTO.getTransferViewSettingDTO().getSelectorType() != null) {
                    row.createCell(16).setCellValue(attributeDTO.getTransferViewSettingDTO().getSelectorType().name());
                }
            }

            Row row = mainSheet.createRow(rowNum + 1);
            row.createCell(0).setCellValue(rowNum);
            row.createCell(1).setCellValue(tableInfoDTO.getTableName());
            row.createCell(2).setCellValue(tableInfoDTO.getPrimaryKeyList().get(0));
            row.createCell(3).setCellValue(tableInfoDTO.getTableComment());
            row.createCell(4).setCellValue("AutoGenerator");
            row.createCell(5).setCellValue(projectDefinitionDO.getServerProjectDefinitionDO().getServerProjectStartClassPackagePathName());
            rowNum++;
        }

        modelInputStream.close();
        workbook.write(outputStream);
        outputStream.close();


    }

    public static void buildExcel(ProjectDefinitionDO projectDefinitionDO, TableInfoDTO tableInfoDTO, String targetFileName) throws Exception {

        String absolutePath = Objects.requireNonNull(SqlConverterHelper.class.getResource("/")).getPath();
        File modelFile = new File(absolutePath + File.separator + "model.xlsx");
        List<AttributeDTO> attributeDTOList = buildAttributeDTOList(tableInfoDTO);
        String tableName = tableInfoDTO.getTableName();
        FileInputStream modelInputStream = new FileInputStream(modelFile);
        File file = new File(targetFileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        // 复制文件内容
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = modelInputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        outputStream.flush();
        outputStream = new FileOutputStream(file);
        modelInputStream = new FileInputStream(modelFile);
        Workbook workbook = new XSSFWorkbook(modelInputStream);
        Sheet sheet = workbook.getSheetAt(0);
        if (sheet != null) {
            workbook.setSheetName(0, tableName);
        } else {
            sheet = workbook.createSheet("account_info");
        }
        int rowIndex = 0;
        for (AttributeDTO attributeDTO : attributeDTOList) {
            Row row = sheet.createRow(4 + rowIndex++);
            row.createCell(0).setCellValue(rowIndex);
            row.createCell(1).setCellValue(attributeDTO.getColumnName());
            row.createCell(2).setCellValue(attributeDTO.getColumnAttribute().getColumnType());
            row.createCell(3).setCellValue(attributeDTO.getColumnAttribute().getAllowNull().toString());
            row.createCell(4).setCellValue(attributeDTO.getColumnAttribute().getColumnLength());
            row.createCell(5).setCellValue(attributeDTO.getColumnAttribute().getShortName());
            row.createCell(6).setCellValue(attributeDTO.getColumnAttribute().getShortComment());
            row.createCell(7).setCellValue(attributeDTO.getColumnAttribute().getDetailComment());

            row.createCell(8).setCellValue(attributeDTO.getJavaAttribute().getAttributeName());
            row.createCell(9).setCellValue(attributeDTO.getJavaAttribute().getAttributeType());

//            if (attributeDTO.getJavaAttribute().getJavaAttributeExtendJson() != null) {
//                row.createCell(10).setCellValue(attributeDTO.getJavaAttribute().getJavaAttributeExtendJson());
//            }

            if (attributeDTO.getJavaAttribute().getSupportEqual() != null) {
                row.createCell(10).setCellValue(attributeDTO.getJavaAttribute().getSupportEqual());
            }
            if (attributeDTO.getJavaAttribute().getSupportIn() != null) {
                row.createCell(11).setCellValue(attributeDTO.getJavaAttribute().getSupportIn());
            }
            if (attributeDTO.getJavaAttribute().getSupportCompare() != null) {
                row.createCell(12).setCellValue(attributeDTO.getJavaAttribute().getSupportCompare());
            }
            if (attributeDTO.getJavaAttribute().getSupportFuzzy() != null) {
                row.createCell(13).setCellValue(attributeDTO.getJavaAttribute().getSupportFuzzy());
            }
            if (attributeDTO.getJavaAttribute().getDtoRules() != null) {
                row.createCell(14).setCellValue(attributeDTO.getJavaAttribute().getDtoRules());
            }
            if (attributeDTO.getJavaAttribute().getDtoRules() != null) {
                row.createCell(15).setCellValue(attributeDTO.getJavaAttribute().getDomainRules());
            }

            if (attributeDTO.getTransferViewSettingDTO().getSelectorType() != null) {
                row.createCell(16).setCellValue(attributeDTO.getTransferViewSettingDTO().getSelectorType().name());
            }
        }
        Sheet mainSheet = workbook.getSheet("main");
        if (mainSheet == null) {
            mainSheet = workbook.createSheet("main");
        }
        int rowNum = mainSheet.getLastRowNum();
        Row row = mainSheet.createRow(rowNum + 1);
        row.createCell(0).setCellValue(rowNum);
        row.createCell(1).setCellValue(tableInfoDTO.getTableName());
        row.createCell(2).setCellValue(tableInfoDTO.getPrimaryKeyList().get(0));
        row.createCell(3).setCellValue(tableInfoDTO.getTableComment());
        row.createCell(4).setCellValue("AutoGenerator");
        row.createCell(5).setCellValue(projectDefinitionDO.getServerProjectDefinitionDO().getServerProjectStartClassPackagePathName());
        modelInputStream.close();
        workbook.write(outputStream);
        outputStream.close();

    }


    public static List<AttributeDTO> buildAttributeDTOList(TableInfoDTO tableInfoDTO) {

        List<ColumnInfoDTO> columnInfoDTOList = tableInfoDTO.getColumnInfoDTOList();
        List<AttributeDTO> attributeDTOList = new ArrayList<>();

        int index = 0;
        for (ColumnInfoDTO columnInfoDTO : columnInfoDTOList) {
            AttributeDTO attributeDTO = new AttributeDTO();
            attributeDTOList.add(attributeDTO);
            attributeDTO.setColumnName(columnInfoDTO.getColumnName());
            ColumnAttributeDTO columnAttributeDTO = buildColumnAttribute(columnInfoDTO, tableInfoDTO);
            columnAttributeDTO.setListOrder(index++);
            attributeDTO.setColumnAttribute(columnAttributeDTO);
            buildJavaAttributeAndViewAttribute(attributeDTO, columnInfoDTO, tableInfoDTO);
        }
        return attributeDTOList;
    }

    public static void buildJavaAttributeAndViewAttribute(AttributeDTO attributeDTO, ColumnInfoDTO columnInfoDTO, TableInfoDTO tableInfoDTO) {
        ColumnAttributeDTO columnAttributeDTO = attributeDTO.getColumnAttribute();

        JavaAttributeDTO javaAttributeDTO = new JavaAttributeDTO();
        attributeDTO.setJavaAttribute(javaAttributeDTO);
        javaAttributeDTO.setColumnName(attributeDTO.getColumnName());
        javaAttributeDTO.setAttributeName(snakeToCamel(columnAttributeDTO.getColumnName()));
        javaAttributeDTO.setAttributeType(convertColumnType(columnAttributeDTO.getColumnType()));

        TransferViewSettingDTO transferViewSettingDTO = new TransferViewSettingDTO();
        transferViewSettingDTO.setColumnName(attributeDTO.getColumnName());
        attributeDTO.setTransferViewSettingDTO(transferViewSettingDTO);

        boolean needSetAgain = true;

        /*
          优先处理保留字段，如主键、创建时间、修改时间，逻辑删除等。
          */
        List<String> dtoValidateList = new ArrayList<>();
        List<String> domainValidateList = new ArrayList<>();
        String comments = getComments(columnInfoDTO.getColumnComment());
        String regex = "enum=\\{(.*?)}";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(comments);
        if (matcher.find()) {
            String patternValue = generatePatternValidation(matcher);
            dtoValidateList.add(patternValue);
            domainValidateList.add(patternValue);
        }

        if (columnAttributeDTO.isPrimaryKey()) {
            javaAttributeDTO.setSupportEqual(BooleanFLAG.Y.name());
            javaAttributeDTO.setSupportIn(BooleanFLAG.Y.name());
            javaAttributeDTO.setDtoRuleList(dtoValidateList);
            javaAttributeDTO.setDomainRuleList(domainValidateList);
            dtoValidateList.add("@Null(message = \"创建记录时，主键唯一标识，不允许设置，由系统自动成生。\", groups = {InsertGroup.class})");
            dtoValidateList.add("@NotNull(message = \"修改记录时，主键唯一标识，必须设置。\", groups = {UpdateGroup.class})");
            domainValidateList.add("@Null(message = \"创建记录时，主键唯一标识，不允许设置，由系统自动成生。\", groups = {InsertGroup.class})");
            domainValidateList.add("@NotNull(message = \"修改记录时，主键唯一标识，必须设置。\", groups = {UpdateGroup.class})");
            transferViewSettingDTO.setSelectorType(SelectorType.NOT_SET);
            needSetAgain = false;
        }

        if (tableInfoDTO.getForeignColumnList().contains(columnAttributeDTO.getColumnName())) {
            javaAttributeDTO.setSupportEqual(BooleanFLAG.Y.name());
            javaAttributeDTO.setSupportIn(BooleanFLAG.Y.name());
            javaAttributeDTO.setDtoRuleList(dtoValidateList);
            javaAttributeDTO.setDomainRuleList(domainValidateList);
            dtoValidateList.add("@Null(message = \"修改记录时，" + columnAttributeDTO.getShortName() + "必须设置。\", groups = {InsertGroup.class})");
            dtoValidateList.add("@Null(message = \"修改记录时，" + columnAttributeDTO.getShortName() + "不允许变更。\", groups = {UpdateGroup.class})");
            domainValidateList.add("@Null(message = \"修改记录时，" + columnAttributeDTO.getShortName() + "必须设置。\", groups = {InsertGroup.class})");
            domainValidateList.add("@Null(message = \"修改记录时，" + columnAttributeDTO.getShortName() + "不允许变更。\", groups = {UpdateGroup.class})");
            transferViewSettingDTO.setSelectorType(SelectorType.NOT_SET);
            needSetAgain = false;
        }

        if (hasStr(attributeDTO.getColumnName(), CREATE_TIME)) {
            javaAttributeDTO.setDtoRuleList(dtoValidateList);
            javaAttributeDTO.setSupportCompare(BooleanFLAG.Y.name());
            transferViewSettingDTO.setSelectorType(SelectorType.COMPARE);
            dtoValidateList.add("@Null(message = \"创建记录时，记录创建时间，不允许设置，由系统自动生成。一经创建不允许修改。\", groups = {InsertGroup.class, UpdateGroup.class})");
            needSetAgain = false;
        }
        if (hasStr(attributeDTO.getColumnName(), UPDATE_TIME)) {
            javaAttributeDTO.setDtoRuleList(dtoValidateList);
            javaAttributeDTO.setSupportCompare(BooleanFLAG.Y.name());
            transferViewSettingDTO.setSelectorType(SelectorType.COMPARE);
            dtoValidateList.add("@Null(message = \"创建记录时和修改记录时，记录修改时间，不允许设置，均由系统自动生成。\", groups = {InsertGroup.class, UpdateGroup.class})");
            needSetAgain = false;
        }

        if ("is_delete".equalsIgnoreCase(columnAttributeDTO.getColumnName())) {
            javaAttributeDTO.setDtoRuleList(dtoValidateList);
            javaAttributeDTO.setDomainRuleList(domainValidateList);
            javaAttributeDTO.setSupportEqual(BooleanFLAG.Y.name());
            transferViewSettingDTO.setSelectorType(SelectorType.NOT_SET);
            dtoValidateList.add("@Pattern(regexp = \"^([YN])$\", message = \"Y:删除;N:不删除\", groups = {InsertGroup.class, UpdateGroup.class})");
            domainValidateList.add("@Pattern(regexp = \"^([YN])$\", message = \"Y:删除;N:不删除\", groups = {InsertGroup.class, UpdateGroup.class})");
            needSetAgain = false;
        }

        //预留字段处理结束。预留字段的处理逻辑是固定的，无需再次判断。
        if (!needSetAgain) {
            return;
        }

        buildJavaAttributeExtendValue(javaAttributeDTO, columnInfoDTO.getColumnComment());

        String type = javaAttributeDTO.getAttributeType();
        JavaAttributeExtendDTO extend = javaAttributeDTO.getJavaAttributeExtendDTO();
        String shortName = columnAttributeDTO != null ? columnAttributeDTO.getShortName() : "";
        boolean notNullable = columnInfoDTO != null && !"Y".equals(columnInfoDTO.getAllowNull());
        boolean isNumberType = "Integer".equals(type) || "Long".equals(type);
        boolean isStringType = "String".equals(type);

        // 构建注解模板
        String notNull = "@NotNull(message = \"%s，【" + shortName + "】%s。\", groups = {%s})";
        String notEmpty = "@NotEmpty(message = \"%s，【" + shortName + "】%s。\", groups = {%s})";
        String mustBeNull = "@Null(message = \"%s，【" + shortName + "】禁止设置。\", groups = {%s})";

        String addNewStr = "新增时";
        String updateStr = "修改时";

        // 插入时处理
        if ((isNumberType || isStringType)) {
            String notSetGroup = "InsertGroup.class";
            String mustSetGroup = "InsertGroup.class";

            if (Boolean.TRUE.equals(extend.getInsertProhibitSet())) {
                dtoValidateList.add(String.format(mustBeNull, addNewStr, notSetGroup));
            } else if (StringUtils.isEmpty(extend.getInitDefaultValue()) && notNullable) {
                String annotationTemplate = isNumberType ? notNull : notEmpty;
                dtoValidateList.add(String.format(annotationTemplate, addNewStr, "必须设置", mustSetGroup));
            }

            // 修改时处理
            notSetGroup = "UpdateGroup.class";
            mustSetGroup = "UpdateGroup.class";

            if (Boolean.TRUE.equals(extend.getUpdateProhibitSet())) {
                dtoValidateList.add(String.format(mustBeNull, updateStr, notSetGroup));
            } else if (Boolean.TRUE.equals(extend.getUpdateMustSet())) {
                String annotationTemplate = isNumberType ? notNull : notEmpty;
                dtoValidateList.add(String.format(annotationTemplate, updateStr, "必须设置", mustSetGroup));
            }

            // domain 层 insert 必填（不考虑 defaultValue）
            if (notNullable) {
                String domainAnnotation = isNumberType
                        ? "@NotNull(message = \"" + addNewStr + "，【" + shortName + "】必须设置。\", groups = {InsertGroup.class})"
                        : "@NotEmpty(message = \"" + addNewStr + "，【" + shortName + "】必须设置。\", groups = {InsertGroup.class})";
                domainValidateList.add(domainAnnotation);
            }
        }


        // 分析设置属性的范围大小校验信息------begin----------------
        if ("String".equals(javaAttributeDTO.getAttributeType())) {
            String length = columnAttributeDTO.getColumnLength();
            if (length != null) {
                if (judgeColumnNotContainEnum(columnAttributeDTO.getDetailComment())) {
                    // 如何是枚举，则不需要校验SIZE，因为会校验格式，范围内的格式都不会超过数据库最大的长度。
                    dtoValidateList.add("@Size(max = " + length + ", message = \"【" + columnAttributeDTO.getShortName() + "】不能超过" + length + "个字符\", groups = {InsertGroup.class, UpdateGroup.class})");
                    domainValidateList.add("@Size(max = " + length + ", message = \"【" + columnAttributeDTO.getShortName() + "】不能超过" + length + "个字符\", groups = {InsertGroup.class, UpdateGroup.class})");
                }
            }

            String attributeName = javaAttributeDTO.getAttributeName().toLowerCase();
            if (attributeName.contains("name") || attributeName.contains("description") || attributeName.contains("comment") || attributeName.contains("mail")) {
                javaAttributeDTO.setSupportFuzzy(BooleanFLAG.Y.name());
            }
            if (attributeName.contains("mail")) {
                javaAttributeDTO.setSupportIn(BooleanFLAG.Y.name());
            }
        }

        if (javaAttributeDTO.getAttributeType().equals("Integer") || javaAttributeDTO.getAttributeType().equals("Long")) {
            if (StringUtils.isNotEmpty(javaAttributeDTO.getJavaAttributeExtendDTO().getMaxValue())) {
                dtoValidateList.add("@Max(value = " + javaAttributeDTO.getJavaAttributeExtendDTO().getMaxValue() + ", message = \"" + columnAttributeDTO.getShortName() + "不能大于" + javaAttributeDTO.getJavaAttributeExtendDTO().getMaxValue() + javaAttributeDTO.getJavaAttributeExtendDTO().getMaxUnit() + "\", groups = {InsertGroup.class, UpdateGroup.class})");
            }
            if (StringUtils.isEmpty(javaAttributeDTO.getJavaAttributeExtendDTO().getInitDefaultValue())) {
                dtoValidateList.add("@Min(value = " + javaAttributeDTO.getJavaAttributeExtendDTO().getMinValue() + ", message = \"" + columnAttributeDTO.getShortName() + "不能小于" + javaAttributeDTO.getJavaAttributeExtendDTO().getMinValue() + javaAttributeDTO.getJavaAttributeExtendDTO().getMinUnit() + "\", groups = {InsertGroup.class, UpdateGroup.class})");
            }
        }
        if ((javaAttributeDTO.getAttributeType().equals("Integer") || javaAttributeDTO.getAttributeType().equals("Long"))
                && containsStr(javaAttributeDTO.getColumnName(), COMPARE_KEY_WORDS)) {
            javaAttributeDTO.setSupportCompare(BooleanFLAG.Y.name());
        }

        // 分析设置属性的范围大小校验信息------end----------------


        if (!dtoValidateList.isEmpty()) {
            javaAttributeDTO.setDtoRuleList(dtoValidateList);
        }

        if (!domainValidateList.isEmpty()) {
            javaAttributeDTO.setDomainRuleList(domainValidateList);
        }

        if ("Date".equals(javaAttributeDTO.getAttributeType())) {
            if (notNullable) {
                if (extend.getInitDefaultValue() == null) {
                    javaAttributeDTO.setDtoRuleList(dtoValidateList);
                    dtoValidateList.add("@NotNull(message = \"" + addNewStr + "，【" + shortName + "】必须设置。\", groups = {InsertGroup.class})");
                }
                javaAttributeDTO.setDomainRuleList(domainValidateList);
                domainValidateList.add("@NotNull(message = \"" + addNewStr + "，【" + shortName + "】必须设置。\", groups = {InsertGroup.class})");
            }
        }

        if (endWithStr(javaAttributeDTO.getColumnName(), IN_END_KEY_WORDS)) {
            if (javaAttributeDTO.getSupportIn() == null) {
                javaAttributeDTO.setSupportIn(BooleanFLAG.Y.name());
                javaAttributeDTO.setSupportEqual(BooleanFLAG.Y.name());
            }
        }

        if (StringUtils.isNotBlank(columnAttributeDTO.getDetailComment()) && columnAttributeDTO.getDetailComment().toLowerCase().contains("enum")) {
            transferViewSettingDTO.setSelectorType(SelectorType.IN);
        } else if (javaAttributeDTO.getAttributeType().equals("String")) {
            transferViewSettingDTO.setSelectorType(SelectorType.FUZZY);
        } else if (javaAttributeDTO.getAttributeType().equals("Date")) {
            transferViewSettingDTO.setSelectorType(SelectorType.COMPARE);
        } else if (javaAttributeDTO.getAttributeType().equals("Integer") || javaAttributeDTO.getAttributeType().equals("Long")) {
            transferViewSettingDTO.setSelectorType(SelectorType.EQUAL);
        } else {
            transferViewSettingDTO.setSelectorType(SelectorType.NOT_SET);
        }
//        if (!"Y".equals(columnInfoDTO.getAllowNull())) {
//            transferViewSettingDTO.setNotInsertFlag("N");
//        }

    }

    public static boolean judgeColumnNotContainEnum(String detailComments) {
        if (StringUtils.isBlank(detailComments)) {
            return true; // 备注为空，不包含枚举
        }
        String lowerComments = detailComments.toLowerCase();
        // 检查是否包含任意枚举标识
        boolean containsEnum = lowerComments.contains("enum=")
                || lowerComments.contains("enum =")
                || lowerComments.contains("enum = ");
        return !containsEnum; // 不包含枚举返回true，包含返回false
    }

    public static void buildJavaAttributeExtendValue(JavaAttributeDTO javaAttributeDTO, String comments) {
        JavaAttributeExtendDTO javaAttributeExtendValueDTO = new JavaAttributeExtendDTO();
        javaAttributeDTO.setJavaAttributeExtendDTO(javaAttributeExtendValueDTO);

        if (comments != null) {
            if (comments.contains("新增时必须设置")) {
                javaAttributeExtendValueDTO.setInsertMustSet(true);
            } else if (comments.contains("新增时禁止设置")) {
                javaAttributeExtendValueDTO.setInsertProhibitSet(true);
            }

            if (comments.contains("修改时必须设置")) {
                javaAttributeExtendValueDTO.setUpdateMustSet(true);
            } else if (comments.contains("修改时禁止设置")) {
                javaAttributeExtendValueDTO.setUpdateProhibitSet(true);
            }
            buildInitDefaultValue(comments, javaAttributeDTO);

        } else {
            comments = javaAttributeDTO.getColumnName();
        }

        if (StringUtils.isNotEmpty(javaAttributeExtendValueDTO.getInitDefaultValue())) {
            javaAttributeExtendValueDTO.setInsertMustSet(false);
        }

        // 提取不能大于【数值(单位)】
        Matcher matcher = Pattern.compile("不能大于【(\\d+(?:\\.\\d+)?)(?:[（(](.*?)[）)])?】").matcher(comments);
        if (matcher.find()) {
            javaAttributeExtendValueDTO.setMaxValue(matcher.group(1).trim());
            String unit = matcher.group(2);
            if (StringUtils.isNotEmpty(unit)) {
                javaAttributeExtendValueDTO.setMaxUnit(unit.trim());
            }
        }

        // 提取不能小于【数值(单位)】
        matcher = Pattern.compile("不能小于【(\\d+(?:\\.\\d+)?)(?:[（(](.*?)[）)])?】").matcher(comments);
        if (matcher.find()) {
            javaAttributeExtendValueDTO.setMinValue(matcher.group(1).trim());
            String unit = matcher.group(2);
            if (StringUtils.isNotEmpty(unit)) {
                javaAttributeExtendValueDTO.setMinUnit(unit.trim());
            }
        }
    }

    public static void buildInitDefaultValue(String comments, JavaAttributeDTO javaAttributeDTO) {
        JavaAttributeExtendDTO javaAttributeExtendValueDTO = javaAttributeDTO.getJavaAttributeExtendDTO();
        if (javaAttributeExtendValueDTO == null) {
            javaAttributeExtendValueDTO = new JavaAttributeExtendDTO();
            javaAttributeDTO.setJavaAttributeExtendDTO(javaAttributeExtendValueDTO);
        }
        if (comments.contains("新增时，如果没有设置，默认初始值为")) {
            String regex = "【(.*?)】";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(comments);
            // 查找匹配内容
            if (matcher.find()) {
                javaAttributeExtendValueDTO.setInitDefaultValue(matcher.group(1));
            }
        }
    }

    public static ColumnAttributeDTO buildColumnAttribute(ColumnInfoDTO columnInfoDTO, TableInfoDTO tableInfoDTO) {
        ColumnAttributeDTO columnAttribute = new ColumnAttributeDTO();
        String comment = getComments(columnInfoDTO.getColumnComment());
        columnAttribute.setColumnName(columnInfoDTO.getColumnName());
        columnAttribute.setColumnType(columnInfoDTO.getColumnType());
        if (columnInfoDTO.getMaxSize() != null) {
            columnAttribute.setColumnLength(columnInfoDTO.getMaxSize().toString());
        }
        columnAttribute.setDetailComment(comment);
        columnAttribute.setAllowNull(columnInfoDTO.getAllowNull().charAt(0));

        columnAttribute.setShortName(getShortName(comment, columnAttribute.getColumnName()));
        if (tableInfoDTO.getPrimaryKeyList().contains(columnInfoDTO.getColumnName())) {
            columnAttribute.setPrimaryKey(true);
        }
        return columnAttribute;
    }


    /**
     * 去掉格式化后开头与结尾的单引号。
     */
    private static String getComments(String comments) {
        if (comments != null && comments.startsWith("'")) {
            comments = comments.substring(1, comments.length() - 1);
        }
        if (comments != null && comments.endsWith("'")) {
            comments = comments.substring(0, comments.length() - 1);
        }
        if (comments != null) {
            return comments.trim();
        }
        return "";
    }

    private static String generatePatternValidation(Matcher matcher) {
        String extractedContent = matcher.group(1);
        String[] array = extractedContent.split(";");
        StringBuilder patternStr = new StringBuilder("@Pattern(regexp = \"^(");
        for (int i = 0; i < array.length; i++) {
            String key = array[i].split(":")[0].trim();
            // @Pattern(regexp = "^(Y|N)$", message = "允许查询, 用于表示资源信息是否允许被所有人查看。Y，表示允许，N表示不允许,只能取{Y、N}", groups = {InsertGroup.class, UpdateGroup.class})
            if (i == 0) {
                patternStr.append(key);
            } else {
                patternStr.append("|").append(key);
            }
        }
        patternStr.append(")$\", message = \"");
        patternStr.append(extractedContent).append("\")");
        return patternStr.toString();
    }

    /**
     * 属性中文名称。
     */
    private static String getShortName(String comments, String columnName) {
        if (StringUtils.isEmpty(comments)) {
            return snakeToCamel(columnName);
        }

        // 定义所有可能的分隔符
        char[] delimiters = {'，', ',', '。', '.'};
        int minIndex = -1;

        for (char delimiter : delimiters) {
            int index = comments.indexOf(delimiter);
            if (index != -1 && (minIndex == -1 || index < minIndex)) {
                minIndex = index;
            }
        }
        return (minIndex != -1) ? comments.substring(0, minIndex) : comments;
    }

    public static String snakeToCamel(String snakeStr) {
        StringBuilder result = new StringBuilder();
        String[] components = snakeStr.split("_");
        for (int i = 0; i < components.length; i++) {
            if (i == 0) {
                result.append(components[i]);
            } else {
                result.append(Character.toUpperCase(components[i].charAt(0))).append(components[i].substring(1));
            }
        }
        return result.toString();
    }

    public static String convertColumnType(String dbColumnType) {
        switch (dbColumnType.toUpperCase()) {
            // 整数类型
            case "INT":
                return "Integer";
            case "TINYINT":
                return "Byte";
            case "SMALLINT":
                return "Short";
            case "MEDIUMINT":
            case "YEAR":
                return "Integer";
            case "BIGINT":
                return "Long";
            // 浮点类型
            case "FLOAT":
                return "Float";
            case "DOUBLE":
                return "Double";
            case "DECIMAL":
                return "java.math.BigDecimal";
            // 字符类型
            case "CHAR":
            case "VARCHAR":
            case "TINYTEXT":
            case "TEXT":
            case "MEDIUMTEXT":
            case "LONGTEXT":
                return "String";
            // 二进制类型
            case "BINARY":
            case "VARBINARY":
            case "TINYBLOB":
            case "BLOB":
            case "MEDIUMBLOB":
            case "LONGBLOB":
                return "byte[]";
            // 日期时间类型
            case "DATE":
            case "TIME":
            case "DATETIME":
            case "TIMESTAMP":
                return "Date";
            default:
                return dbColumnType;
        }
    }

    public static boolean hasStr(String str, String[] arr) {
        for (String s : arr) {
            if (str.equalsIgnoreCase(s)) {
                return true;
            }
        }
        return false;
    }

    public static boolean containsStr(String str, String[] arr) {
        for (String s : arr) {
            if (str.toLowerCase().contains(s.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    public static boolean endWithStr(String str, String[] arr) {
        for (String s : arr) {
            if (str.toLowerCase().endsWith(s.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    public static String[] CREATE_TIME = {"gmt_create", "create_at", "create_time"};
    public static String[] UPDATE_TIME = {"gmt_update", "update_at", "update_time"};
    public static String[] COMPARE_KEY_WORDS = {"price", "percent", "amount", "count", "total", "range", "rate", "ratio", "discount", "volume"};
    public static String[] IN_END_KEY_WORDS = {"id", "status", "year", "type", "code", "flag", "_no"};

}
